#include <algorithm>
#include <cstdio>
using namespace std;

int n, m;
struct Edge {
	int v, w, u;
	friend bool operator<(const Edge &a, const Edge &b) {
		return a.w < b.w;
	}
} e[1000];
int cnt, heads[1000];
inline void add(int u, int v, int w) {
	e[cnt].v = v;
	e[cnt].w = w;
	e[cnt++].u = u;
}
int f[1000];
int main() {
	freopen("testdata.in", "r", stdin);
	freopen("testdata.out", "w", stdout);
	freopen("bridge.in", "r", stdin);
	freopen("bridge.out", "w", stdout);
	scanf("%d%d", &n, &m);
	int tmp1, tmp2, tmp3;
	for (int i = 0; i < m; ++i) {
		scanf("%d%d%d", &tmp1, &tmp2, &tmp3);
		add(tmp1, tmp2, tmp3);
	}
	int last = -1;
	int tmp[1000];
	sort(e, e + m);
	for (int i = 0; i < m; ++i) {
		if (e[i].w == e[i + 1].w) continue;
		for (int j = last + 1; j <= i; ++j) {
			tmp[e[j].u] = f[e[j].u];
			tmp[e[j].v] = f[e[j].v];
		}
		for (int j = last + 1; j <= i; ++j) {
			f[e[j].u] = max(f[e[j].u], tmp[e[j].v] + 1);
			f[e[j].v] = max(f[e[j].v], tmp[e[j].u] + 1);
		}
		last = i;
	}
	int ans = 0;
	for (int i = 0; i < n; ++i)
		ans = max(ans, f[i]);
	printf("%d", ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}